package org.mch.comm.ftp;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

/**
 * 描述：文件DES加密工具类；<BR>
 * 
 * 类名：FileDESEncrypt.java<BR>
 * 
 * @author zl；DateTime：2007-6-2<BR>
 * 
 *         说明：<BR>
 * <BR>
 */
public class FileDESEncrypt {

	private String secretkey;

	public FileDESEncrypt(String secretkey) {
		this.secretkey = secretkey;
	}

	/**
	 * 功能：根据当前的密文【加密】传入的二进制流<br>
	 * 
	 * 说明：<br>
	 * 
	 * @author：zl；Date：2007-6-10<br>
	 * 
	 * @param bytes
	 * @return
	 * @throws Exception
	 */
	public byte[] encryptBytes(byte[] bytes) throws Exception {

		return this.encrypt(bytes);
	}

	/**
	 * 功能：根据当前的密文【加密】传入的文件<br>
	 * 
	 * @author：zl；Date：2007-5-31<br>
	 * @param file
	 * @return
	 * @throws Exception
	 */
	public byte[] encryptFile(File file) throws Exception {

		byte[] file_byte = this.getFileBytes(file);

		byte[] encrypt_byte = this.encrypt(file_byte);

		return encrypt_byte;
	}

	/**
	 * 功能：根据当前的密文【解密】传入的文件<br>
	 * 
	 * @author：zl；Date：2007-5-31<br>
	 * @param file
	 * @return
	 * @throws Exception
	 */
	public File decryptFile(File file) throws Exception {

		byte[] file_byte = this.getFileBytes(file);

		byte[] encrypt_byte = this.encrypt(file_byte);

		FileInputStream fis = new FileInputStream(new File("c://test2.txt"));
		try {
			fis.read(encrypt_byte);
		} finally {
			fis.close();
		}

		FileOutputStream fos = new FileOutputStream(new File("c://test2.txt"));
		try {
			fos.write(encrypt_byte);
		} finally {
			fos.flush();
			fos.close();
		}

		return file;
	}

	/**
	 * 功能：根据当前的密文【解密】传入的二进制流；<br>
	 * 
	 * @author：zl；Date：2007-6-3<br>
	 * @param bytes
	 * @return
	 * @throws Exception
	 */
	public byte[] decryptBytes(byte[] bytes) throws Exception {

		return this.decrypt(bytes);
	}

	/**
	 * 功能：将传入的文件转换成字节数组<br>
	 * 
	 * @author：zl；Date：2007-5-31<br>
	 * @param file
	 * @return
	 * @throws Exception
	 */
	public byte[] getFileBytes(File file) throws Exception {

		List<Byte> blist = new ArrayList<Byte>();

		FileInputStream fis = new FileInputStream(file);

		try {
			Integer i;
			while ((i = fis.read()) != -1) {
				blist.add(i.byteValue());
			}
		} finally {
			fis.close();
		}

		byte[] b = new byte[blist.size()];
		for (int k = 0; k < blist.size(); k++) {
			b[k] = blist.get(k);
		}

		return b;
	}

	private byte[] encrypt(byte[] bytIn) {
		try {
			byte[] bytK1 = getKeyByStr(this.secretkey.substring(0, 16));
			byte[] bytK2 = getKeyByStr(this.secretkey.substring(16, 32));
			byte[] bytK3 = getKeyByStr(this.secretkey.substring(32, 48));
			byte[] bytOut = encryptByDES(encryptByDES(encryptByDES(bytIn, bytK1), bytK2), bytK3);
			System.out.println("加密成功！");
			return bytOut;

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	private byte[] decrypt(byte[] bytIn) {
		try {
			byte[] bytK1 = getKeyByStr(this.secretkey.substring(0, 16));
			byte[] bytK2 = getKeyByStr(this.secretkey.substring(16, 32));
			byte[] bytK3 = getKeyByStr(this.secretkey.substring(32, 48));
			byte[] bytOut = decryptByDES(decryptByDES(decryptByDES(bytIn, bytK3), bytK2), bytK1);
			System.out.println("解密成功！");
			return bytOut;

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	private byte[] getKeyByStr(String str) {
		byte[] bRet = new byte[str.length() / 2];
		for (int i = 0; i < str.length() / 2; i++) {
			Integer itg = new Integer(16 * getChrInt(str.charAt(2 * i)) + getChrInt(str.charAt(2 * i + 1)));
			bRet[i] = itg.byteValue();
		}
		return bRet;
	}

	private int getChrInt(char chr) {
		int iRet = 0;
		if (chr == "0".charAt(0))
			iRet = 0;
		if (chr == "1".charAt(0))
			iRet = 1;
		if (chr == "2".charAt(0))
			iRet = 2;
		if (chr == "3".charAt(0))
			iRet = 3;
		if (chr == "4".charAt(0))
			iRet = 4;
		if (chr == "5".charAt(0))
			iRet = 5;
		if (chr == "6".charAt(0))
			iRet = 6;
		if (chr == "7".charAt(0))
			iRet = 7;
		if (chr == "8".charAt(0))
			iRet = 8;
		if (chr == "9".charAt(0))
			iRet = 9;
		if (chr == "A".charAt(0))
			iRet = 10;
		if (chr == "B".charAt(0))
			iRet = 11;
		if (chr == "C".charAt(0))
			iRet = 12;
		if (chr == "D".charAt(0))
			iRet = 13;
		if (chr == "E".charAt(0))
			iRet = 14;
		if (chr == "F".charAt(0))
			iRet = 15;
		return iRet;
	}

	private byte[] encryptByDES(byte[] bytP, byte[] bytKey) throws Exception {
		DESKeySpec desKS = new DESKeySpec(bytKey);
		SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
		SecretKey sk = skf.generateSecret(desKS);
		Cipher cip = Cipher.getInstance("DES");
		cip.init(Cipher.ENCRYPT_MODE, sk);
		return cip.doFinal(bytP);
	}

	private byte[] decryptByDES(byte[] bytE, byte[] bytKey) throws Exception {
		DESKeySpec desKS = new DESKeySpec(bytKey);
		SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
		SecretKey sk = skf.generateSecret(desKS);
		Cipher cip = Cipher.getInstance("DES");
		cip.init(Cipher.DECRYPT_MODE, sk);
		return cip.doFinal(bytE);

		// // DES算法要求有一个可信任的随机数源
		// SecureRandom sr = new SecureRandom();
		// // 从原始密匙数据创建一个DESKeySpec对象
		// DESKeySpec dks = new DESKeySpec(bytKey);
		// // 创建一个密匙工厂，然后用它把DESKeySpec对象转换成
		// // 一个SecretKey对象
		// SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
		// SecretKey securekey = keyFactory.generateSecret(dks);
		// // Cipher对象实际完成解密操作
		// Cipher cipher = Cipher.getInstance("DES");
		// // 用密匙初始化Cipher对象
		// cipher.init(Cipher.DECRYPT_MODE, securekey, sr);
		// // 现在，获取数据并解密
		// // 正式执行解密操作
		// return cipher.doFinal(bytE);

	}

	public static void main(String[] args) throws Exception {
		// List<Byte> blist = new ArrayList<Byte>();
		//
		// File file = new File("c://test.txt");
		// FileInputStream fis = new FileInputStream(file);
		//
		// Integer i = fis.read();
		// while (i != -1) {
		// blist.add(i.byteValue());
		// i = fis.read();
		// }
		//
		// byte[] b = new byte[blist.size()];
		// for (int k = 0; k < blist.size(); k++) {
		// b[k] = blist.get(k);
		// }
		//
		// FileOutputStream fos = new FileOutputStream(new
		// File("c://test2.txt"));
		// fos.write(b);
		// fos.flush();
		// fos.close();

		try {

			// FileDESEncrypt fe = new FileDESEncrypt(
			// "AD67EA2F3BE6E5ADD368DFE03120B5DF92A8FD8FEC2F0746");
			//
			// byte[] file_byte = fe.getFileBytes(new File("c://test.ini"));
			//
			// byte[] encrypt_byte = fe.encrypt(file_byte);
			//
			// FileOutputStream fos = new FileOutputStream(new File(
			// "c://test加密.txt"));
			// fos.write(encrypt_byte);
			//
			// fos.flush();
			// fos.close();

			FileDESEncrypt fed = new FileDESEncrypt("AD67EA2F3BE6E5ADD368DFE03120B5DF92A8FD8FEC2F0746");

			byte[] encryptfile_byte = fed.getFileBytes(new File("c://test加密.txt"));

			byte[] decrypt_byte = fed.decrypt(encryptfile_byte);

			FileOutputStream fos_d = new FileOutputStream(new File("c://test解密.txt"));
			fos_d.write(decrypt_byte);

			fos_d.flush();
			fos_d.close();

		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
